<template>
  <div class="jeecg-basic-table-form-container p-0">
    <BasicForm ref="onlineQueryFormRef" @register="registerForm">
      <template #groupDate="{ model, field }">
        <a-date-picker
          :showTime="false"
          valueFormat="YYYY-MM-DD"
          placeholder="开始日期"
          v-model:value="model[field + '_begin']"
          style="width: calc(50% - 15px); min-width: 100px"
        />
        <span class="group-query-strig">~</span>
        <a-date-picker
          :showTime="false"
          valueFormat="YYYY-MM-DD"
          placeholder="结束日期"
          v-model:value="model[field + '_end']"
          style="width: calc(50% - 15px); min-width: 100px"
        />
      </template>
      <template #groupDatetime="{ model, field }">
        <a-date-picker
          :showTime="false"
          valueFormat="YYYY-MM-DD HH:mm:ss"
          placeholder="开始日期"
          v-model:value="model[field + '_begin']"
          style="width: calc(50% - 15px); min-width: 100px"
        />
        <span class="group-query-strig">~</span>
        <a-date-picker
          :showTime="false"
          valueFormat="YYYY-MM-DD HH:mm:ss"
          placeholder="结束日期"
          v-model:value="model[field + '_end']"
          style="width: calc(50% - 15px); min-width: 100px"
        />
      </template>
      <template #groupNumber="{ model, field }">
        <a-input-number placeholder="开始值" v-model:value="model[field + '_begin']" style="width: calc(50% - 15px)" />
        <span class="group-query-strig">~</span>
        <a-input-number placeholder="结束值" v-model:value="model[field + '_end']" style="width: calc(50% - 15px)" />
      </template>
      <template #formFooter>
        <a-col :md="6" :sm="8">
          <span style="float: left; overflow: hidden; margin-left: 10px" class="table-page-search-submitButtons">
            <a-button preIcon="ant-design:search" type="primary" @click="doSearch">查询</a-button>
            <a-button preIcon="ant-design:reload" type="primary" @click="resetSearch" style="margin-left: 8px">重置</a-button>
            <a v-if="toggleButtonShow" style="margin-left: 8px" @click="($event) => ($setup.toggleSearchStatus = !$setup.toggleSearchStatus)">
              {{ toggleSearchStatus ? '收起' : '展开' }}
              <Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
            </a>
          </span>
        </a-col>
      </template>
    </BasicForm>
  </div>
</template>
<script lang="ts">
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { ref, reactive, watch, toRaw, defineComponent } from 'vue';
  import { defHttp } from '/@/utils/http/axios';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { FORM_VIEW_TO_QUERY_VIEW, FormSchemaFactory } from '../../use/FormSchemaFactory';
  import { getRefPromise, loadOneFieldDefVal, LINK_DOWN, handleLinkDown, getFieldIndex } from '../../use/useAutoForm';

  export default defineComponent({
    name: 'OnlineQueryForm',
    components: {
      BasicForm,
    },
    props: {
      id: {
        type: String,
        default: '',
      },
    },
    emits: ['search', 'loaded'],
    setup(props, { emit }) {
      const LOAD_URL = '/api-online/online/cgform/api/getQueryInfoVue3/';
      const onlineQueryFormRef = ref(null);
      const formSchemas = ref([]);
      const baseColProps = ref({ xs: 24, sm: 24, md: 12, lg: 6, xl: 6 });
      const toggleButtonShow = ref(false);
      const toggleSearchStatus = ref(false);
      const queryParams = ref({});
      const hideList = ref([]);
      const { createMessage: $message } = useMessage();
      const defaultValues = reactive({
        config: {},
        cache: {},
        param: {},
        status: false,
      });
      watch(
        () => defaultValues.status,
        async (val) => {
          console.log('-------------defaultValues发生改变,需要重置表单---------------');
          const { config, cache, param } = toRaw(defaultValues);
          let rawValues = Object.assign({}, config, cache, param);
          await customSetFieldsValue(rawValues);
        },
        { immediate: true, deep: true }
      );
      async function initDefaultValues(cache, param) {
        defaultValues.cache = Object.assign({}, cache);
        defaultValues.param = Object.assign({}, param);
        defaultValues.status = !defaultValues.status;
      }
      watch(
        () => props.id,
        (val) => {
          if (val) {
            resetForm();
          } else {
            formSchemas.value = [];
          }
        },
        { immediate: true }
      );
      async function initSchemas(formProperties) {
        let arr = [];
        let configValue = {};
        let keys = Object.keys(formProperties);
        for (let key of keys) {
          const item = formProperties[key];
          let view = item.view;
          if (FORM_VIEW_TO_QUERY_VIEW[view]) {
            item.view = FORM_VIEW_TO_QUERY_VIEW[view];
          }
          await loadOneFieldDefVal(key, item, configValue);
          if (item.mode == 'group' && ('date' == view || 'datetime' == view || 'number' == view)) {
            let temp = FormSchemaFactory.createSlotFormSchema(key, item);
            arr.push(temp);
          } else {
            if (item.view === LINK_DOWN) {
              let array = handleLinkDown(item, key);
              for (let linkDownItem of array) {
                let temp = FormSchemaFactory.createFormSchema(linkDownItem.key, linkDownItem);
                let tempIndex = getFieldIndex(arr, linkDownItem.key);
                if (tempIndex == -1) {
                  arr.push(temp);
                } else {
                  arr[tempIndex] = temp;
                }
              }
            } else {
              let tempIndex = getFieldIndex(arr, key);
              if (tempIndex == -1) {
                let temp = FormSchemaFactory.createFormSchema(key, item);
                arr.push(temp);
              }
            }
          }
        }
        arr.sort(function (a, b) {
          return a.order - b.order;
        });
        let schemaArray = [];
        if (arr.length > 2) {
          toggleButtonShow.value = true;
        }
        let hideFieldName = [];
        for (let i = 0; i < arr.length; i++) {
          let item = arr[i];
          item.setFormRef(onlineQueryFormRef);
          item.noChange();
          item.asSearchForm();
          if (i > 1) {
            hideFieldName.push(item.field);
            item.isHidden();
          }
          let tempSchema = item.getFormItemSchema();
          if (item.slot == 'groupDatetime') {
            tempSchema['colProps'] = { xs: 24, sm: 24, md: 12, lg: 8, xl: 8 };
          }
          schemaArray.push(tempSchema);
        }
        hideList.value = hideFieldName;
        formSchemas.value = schemaArray;
        defaultValues.config = Object.assign({}, configValue);
        defaultValues.status = !defaultValues.status;
      }
      async function resetForm() {
        let json = await loadQueryInfo();
        console.log('wang++++++++++++', json);
        let allFields = getAllFields(json);
        emit('loaded', json);
        let { formProperties, hasField } = getQueryFormProperties(allFields, json);
        if (hasField == false) {
          formSchemas.value = [];
          return;
        }
        await initSchemas(formProperties);
      }
      async function customSetFieldsValue(rawValues) {
        await getRefPromise(onlineQueryFormRef);
        console.log('rawValues', rawValues);
        await setFieldsValue(rawValues);
        if (Object.keys(rawValues).length > 0) {
          doSearch();
        }
      }
      function getQueryFormProperties(allFields, json) {
        const { searchFieldList, joinQuery, table } = json;
        let hasField = false;
        let formProperties = {};
        if (allFields) {
          Object.keys(allFields).map((field) => {
            if (searchFieldList.indexOf(field) >= 0) {
              if (joinQuery == true) {
                if (field.indexOf('@') < 0) {
                  formProperties[table + '@' + field] = allFields[field];
                  hasField = true;
                } else {
                  formProperties[field] = allFields[field];
                  hasField = true;
                }
              } else {
                if (field.indexOf('@') < 0) {
                  formProperties[field] = allFields[field];
                  hasField = true;
                }
              }
            }
          });
        }
        return {
          formProperties,
          hasField,
        };
      }
      function getAllFields(json) {
        const { properties, searchFieldList, joinQuery, table } = json;
        let allFields = {};
        let order = 1;
        Object.keys(properties).map((field) => {
          let item = properties[field];
          if (item.view == 'table') {
            let subProps = item['properties'];
            let subTableOrder = order * 100;
            Object.keys(subProps).map((subField) => {
              let subItem = subProps[subField];
              subItem['order'] = subTableOrder + Number(subItem['order']);
              let subFieldKey = field + '@' + subField;
              allFields[subFieldKey] = subItem;
            });
            order++;
          } else {
            item['order'] = Number(item['order']);
            allFields[field] = item;
          }
        });
        return allFields;
      }
      function loadQueryInfo() {
        let url = `${LOAD_URL}${props.id}`;
        return new Promise((resolve) => {
          defHttp
            .get({ url }, { isTransformResponse: false })
            .then((res) => {
              if (res.success) {
                resolve(res.data);
              } else {
                resolve(false);
                $message.warning(res.msg);
              }
            })
            .catch(() => {
              $message.warning('获取查询条件失败!');
              resolve(false);
            });
        });
      }
      const [registerForm, { resetFields, setFieldsValue, updateSchema, getFieldsValue }] = useForm({
        schemas: formSchemas,
        showActionButtonGroup: false,
        baseColProps,
        autoSubmitOnEnter: true,
        submitFunc() {
          doSearch();
        },
      });
      function doSearch() {
        let formValues = getFieldsValue();
        let data = Object.assign({}, toRaw(defaultValues.param), changeDataIfArray2String(formValues));
        emit('search', data, true);
      }
      async function resetSearch() {
        await resetFields();
        const { config, param } = toRaw(defaultValues);
        let rawValues = Object.assign({}, config, param);
        if (Object.keys(rawValues).length > 0) {
          await setFieldsValue(rawValues);
        }
        emit('search', rawValues, false);
      }
      function changeDataIfArray2String(data) {
        Object.keys(data).map((k) => {
          if (data[k]) {
            if (data[k] instanceof Array) {
              data[k] = data[k].join(',');
            }
          }
        });
        return data;
      }
      watch(
        () => toggleSearchStatus.value,
        (status) => {
          let names = hideList.value;
          if (names && names.length > 0) {
            let arr = [];
            for (let name of names) {
              arr.push({
                field: name,
                show: status,
              });
            }
            updateSchema(arr);
          }
        },
        { immediate: false }
      );
      return {
        onlineQueryFormRef,
        registerForm,
        initDefaultValues,
        toggleButtonShow,
        toggleSearchStatus,
        doSearch,
        resetSearch,
        queryParams,
        formSchemas,
      };
    },
  });
</script>
<style scoped>
  .group-query-strig {
    width: 30px;
    text-align: center;
    display: inline-block;
  }
</style>
